// 函数式编程范式
// 使用高阶函数的意义：抽象可以帮我们屏蔽细节，只需要关注与我们的目标。高阶函数是用来抽象通用的问题
// 1.函数作为参数
function forEach (array, fn) {
  for (let value of array) {
    fn(value)
  }
}

function filter (array, fn) {
  const res = []
  for (let value of array) {
    if (fn(value)) {
      res.push(value)
    }
  }
  return res
}

const arr = [1,2,3,4,3,2,1]
forEach(arr, value => {
  console.log(value)
})

console.log(filter(arr, value => value%2 === 0))

// 2.函数作为返回值
function makeFn() {
  let msg = 'hello function'
  return function () {
    console.log(msg)
  }
}

const fn = makeFn()

fn() // hello function

makeFn()() // hello function

// 应用：once函数 只执行一次的函数，比如说支付情况，无论用户点击多少次，这个函数都只执行一次
function once (fn) {
  let done = false
  return function () {
    if(!done) {
      done = true
      fn.apply(this, arguments)
    }
  }
}

let pay = once(function (money) {
  console.log(`支付了${money}元`)
})

pay(1) // 支付了1元
pay(2)
pay(3)

// 常用的高阶函数：
// forEach/map/filter/every/some/find/findIndex/reduce/sort